package com.qc31.monitorlib.ui.carmonitor

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.location.Location
import android.net.Uri
import android.view.Gravity
import android.view.View
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import autodispose2.autoDispose
import com.amap.api.maps.AMap
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.Marker
import com.qc31.baselib.rx.LiveDataBus
import com.qc31.baselib.rx.queryThrottle
import com.qc31.baselib.utils.*
import com.qc31.baselib.utils.ActivityResultUtil.launchAct
import com.qc31.baselib.utils.ActivityResultUtil.registerResultOk
import com.qc31.comlib.Keys
import com.qc31.comlib.NetDataUtil
import com.qc31.comlib.entity.GpsDetail
import com.qc31.monitorlib.login.LocationStatusModel
import com.qc31.monitorlib.ui.popup.ChooseNaviPopup
import com.qc31.monitorlib.R
import com.qc31.monitorlib.base.BaseMapLocationFragment
import com.qc31.monitorlib.databinding.FragmentMapCarBinding
import com.qc31.monitorlib.databinding.IncludeCarMapInfoBinding
import com.qc31.monitorlib.databinding.IncludeMapPlateTrafficBinding
import com.qc31.monitorlib.ui.adapter.CarInfoAdapter
import com.qc31.monitorlib.ui.carinfo.CarInfoActivity
import com.qc31.monitorlib.ui.line.HistoryLineActivity
import com.qc31.monitorlib.ui.other.InfoSetActivity
import com.qc31.monitorlib.ui.photo.PhotosActivity
import com.qc31.monitorlib.ui.popup.LegendPopup
import com.qc31.monitorlib.ui.singlemap.SingleMonitorActivity
import com.qc31.monitorlib.uitls.ColorUtil
import com.qc31.monitorlib.uitls.MapUtil
import com.qc31.monitorlib.uitls.MarkerBitmapUtil
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers

/** @Author Jasper @Time 2020/7/22 @Desc 车辆 地图监控 */
class CarMapFragment :
    BaseMapLocationFragment<FragmentMapCarBinding>(FragmentMapCarBinding::inflate) {
    private var mMarker: Marker? = null
    private var mLatLng: LatLng? = null
    private var mLocationLatLng: LatLng? = null
    private lateinit var mTrafficVB: IncludeMapPlateTrafficBinding
    private lateinit var mInfoVB: IncludeCarMapInfoBinding
//    private val wxViewModel by viewModels<WxShareModel>()
    private var mLocationMarker: Marker? = null

    //是否定位
    private var isLocation = false

    //是否展示彈窗
    private var isShowPopup = true

    private val popupLegend: LegendPopup by lazy { LegendPopup(requireContext()) }
    private val mViewModel: CarMapViewModel by viewModels()
    private val mActivityVM by activityViewModels<CarMonitorViewModel>()

    override fun initView(view: View) {

        mTrafficVB = IncludeMapPlateTrafficBinding.bind(binding.root)
        mInfoVB = IncludeCarMapInfoBinding.bind(binding.root)
        mMap?.setInfoWindowAdapter(object : AMap.InfoWindowAdapter {
            override fun getInfoWindow(p0: Marker?): View? {
                val textView = TextView(requireContext())
                textView.text = getString(R.string.desc_location_now)
                textView.gravity = Gravity.CENTER
                return textView
            }

            override fun getInfoContents(p0: Marker?): View? {
                return null
            }
        })
        mMap?.run {
            MapUtil.initMapSetting(this)
            setOnMarkerClickListener {
                if (it == mMarker) {
                    mMap?.mapScreenMarkers?.forEach { marker ->
                        if (marker != mMarker) marker.remove()
                    }
                    isShowPopup = true
                    mTrafficVB.tvCarCarShow.setText(R.string.desc_com_hide)
                    mInfoVB.llCarInfo.visibility = View.VISIBLE
                    MapUtil.showLatLngZoom(this, it.position)
                } else if (it == mLocationMarker) {
                    it.showInfoWindow()
                }
                return@setOnMarkerClickListener true
            }
            mapType = mViewModel.mMapType
            isTrafficEnabled = mViewModel.isCarTraffic
        }
        mTrafficVB.ivCarTraffic.isSelected = mViewModel.isCarTraffic
        if (mViewModel.mMapType == AMap.MAP_TYPE_NORMAL) {
            mTrafficVB.tvCarMapState.setText(R.string.desc_com_map_state_normal)
        } else {
            mTrafficVB.tvCarMapState.setText(R.string.desc_com_map_state_satellite)
        }
        if (mViewModel.isCarName) {
            mTrafficVB.tvCarCarState.setText(R.string.desc_car_name)
        } else {
            mTrafficVB.tvCarCarState.setText(R.string.desc_car_plate)
        }
        infoView()
        infoEvent()
    }

    override fun initData() {
        mActivityVM.carId.observe(this) {
            if (mMarker != null) {
                mInfoVB.llCarInfo.visibility = View.GONE
                mMarker!!.remove()
                mMarker = null
            }
            mMap?.clear()

            mViewModel.carId = it
            isShowPopup = true
            mTrafficVB.tvCarCarShow.setText(R.string.desc_com_hide)
        }


        mViewModel.toastObserver()
            .observeOn(AndroidSchedulers.mainThread()).autoDispose(scopeProvider)
            .subscribe(this::toastObserver)

        mViewModel.locationSub.hide().autoDispose(scopeProvider).subscribe {
            it.run {
                if (glat.isEmpty() || glng.isEmpty()) return@run
                mLatLng = LatLng(glat.toDouble(), glng.toDouble())
                val bitmapDes =
                    MarkerBitmapUtil.getBitmapDes(
                        requireContext(),
                        carId, state, drct, carName, carPlate, iconLink, mViewModel.isCarName, speed
                    )
                if (mMarker == null) {
                    mMarker = MapUtil.addAndGetMarker(mMap!!, mLatLng!!, bitmapDes)
                } else {
                    mMarker?.run {
                        position = mLatLng
                        setIcon(bitmapDes)
                    }
                }
                if (isShowPopup) {
                    MapUtil.showLatLngZoom(mMap!!, mLatLng!!)
                    mInfoVB.llCarInfo.visibility = View.VISIBLE
                    initInfo()
                }

            }
        }
        mViewModel.legendSub.hide().autoDispose(scopeProvider).subscribe({
            popupLegend.showAtLocation(binding.ivCarCarLegend, it)
        }, {
            showToast(it.message ?: getString(R.string.toast_no_back_error_info))
        })
    }

    //是否隐藏状态变化监听
    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (hidden) {
            mViewModel.stopTime()
            mViewModel.isHidden = true
        } else {
            mViewModel.isHidden = false
            mViewModel.carId?.let {
                mViewModel.startTime(it)
            }
        }
    }

    override fun onResume() {
        super.onResume()
        mViewModel.isHidden = false

        mViewModel.carId?.let {
            mViewModel.startTime(it)
        }
    }

    override fun onPause() {
        super.onPause()
        mViewModel.stopTime()
        mViewModel.isHidden = true
    }

    override fun initEvent() {
        mTrafficVB.tvCarMapState.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (mViewModel.mMapType == AMap.MAP_TYPE_NORMAL) {
                mViewModel.mMapType = AMap.MAP_TYPE_SATELLITE
                mMap?.mapType = AMap.MAP_TYPE_SATELLITE
                mTrafficVB.tvCarMapState.setText(R.string.desc_com_map_state_satellite)
            } else {
                mViewModel.mMapType = AMap.MAP_TYPE_NORMAL
                mMap?.mapType = AMap.MAP_TYPE_NORMAL
                mTrafficVB.tvCarMapState.setText(R.string.desc_com_map_state_normal)
            }
        }
        mTrafficVB.tvCarCarState.queryThrottle().autoDispose(scopeProvider).subscribe {
            mViewModel.isCarName = !mViewModel.isCarName
            if (mViewModel.isCarName) {
                mTrafficVB.tvCarCarState.setText(R.string.desc_car_name)
            } else {
                mTrafficVB.tvCarCarState.setText(R.string.desc_car_plate)
            }
            mViewModel.refresh()
        }

        mTrafficVB.ivCarTraffic.queryThrottle().autoDispose(scopeProvider).subscribe {
            mViewModel.isCarTraffic = !mViewModel.isCarTraffic
            mTrafficVB.ivCarTraffic.isSelected = mViewModel.isCarTraffic
            mMap?.isTrafficEnabled = mViewModel.isCarTraffic

        }

        binding.ivCarLocation.queryThrottle().autoDispose(scopeProvider).subscribe {
            isLocation = true
            getPermissions(false)
        }

        binding.ivCarCarLocation.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (mLatLng == null) {
                showToast(R.string.hint_toast_choose_car)
            } else {
                isShowPopup = true
                mTrafficVB.tvCarCarShow.setText(R.string.desc_com_hide)
                mInfoVB.llCarInfo.visibility = View.VISIBLE
                MapUtil.showLatLngZoom(mMap!!, mLatLng!!)
            }

        }

        binding.ivCarCarLegend.queryThrottle().autoDispose(scopeProvider).subscribe {
            mViewModel.getLegend(mViewModel.carId)
        }

        mTrafficVB.tvCarCarShow.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (mViewModel.carId.isNullOrEmpty()) {
                showToast(R.string.hint_toast_choose_car)
                return@subscribe
            }
            if (mViewModel.locaEntity == null) {
                showToast(R.string.toast_no_location_msg)
                return@subscribe
            }
            if (isShowPopup) {
                isShowPopup = false
                mTrafficVB.tvCarCarShow.setText(R.string.desc_com_display)
                mInfoVB.llCarInfo.visibility = View.GONE
            } else {
                isShowPopup = true
                mTrafficVB.tvCarCarShow.setText(R.string.desc_com_hide)
                mInfoVB.llCarInfo.visibility = View.VISIBLE
            }
        }
    }


    override fun onDestroy() {
        mMap?.setInfoWindowAdapter(null)
        MarkerBitmapUtil.recycleLruCache()
        super.onDestroy()
    }

    private val runSpeed by lazy { getString(R.string.desc_run_speed) }
    private val dayMile by lazy { getString(R.string.desc_day_mile) }

    @SuppressLint("SetTextI18n")
    fun initInfo() {
        mViewModel.locaEntity?.run {
            mInfoVB.tvPlateName.text = sub(if (mViewModel.isCarName) carName else carPlate, 14)
            mInfoVB.tvCarRunSpeed.text = "$speed km/h\n$runSpeed"
            mInfoVB.tvCarRunStop.text = runStopTime
            mInfoVB.tvCarDayMile.text = "$preMile km\n$dayMile"
            mInfoVB.tvCarTotalMile.text = "$mile km"
            mInfoVB.tvCarTime.text = "${getString(R.string.desc_location_time)}：$time"

            val colorCode: String = if (plateColorCode.isNullOrEmpty()) {
                NetDataUtil.getColorByName(plateColor)
            } else {
                plateColorCode!!
            }
            when (colorCode) {
                "6", "93", "224" -> {
                    mInfoVB.tvPlateName.setBackgroundResource(R.drawable.ic_color_plate_93)
                }
                "94", "225" -> {
                    mInfoVB.tvPlateName.setBackgroundResource(R.drawable.ic_color_plate_94)
                }
                else -> {
                    val colorDrawable = ColorDrawable()
                    colorDrawable.color = Color.parseColor(ColorUtil.getPlateColor(colorCode))
                    mInfoVB.tvPlateName.background = colorDrawable
                }
            }
            mInfoVB.tvPlateName.setTextColor(Color.parseColor(ColorUtil.getPlateTextColor(colorCode)))
            mInfoVB.tvCarPhoto.text = getString(R.string.desc_marker_photo)
        }
        if (isShowRecycler) {
            showInfoRecycler()
        }

    }

    private val mInfoAdapter by lazy { CarInfoAdapter() }
    private fun infoView() {
        mInfoVB.recyclerCarInfo.layoutManager = LinearLayoutManager(requireContext())
        mInfoVB.recyclerCarInfo.adapter = mInfoAdapter
        mInfoVB.tvCarHistory.visibility = View.GONE
        mInfoVB.vLine.visibility = View.GONE
        mInfoVB.ivCarShare.isVisible = !BuildConfigs.ISGOOGLE && BuildConfigs.ISCOMPANY
    }

    private fun showInfoRecycler() {
        mInfoAdapter.setList(LocationStatusModel.upData(mViewModel.locaEntity))
    }

    //是否展示列表
    private var isShowRecycler = false

    /** 设置info点击事件 */
    private fun infoEvent() {
        LiveDataBus.get().with("upInfoState").observe(this) {
            if (mViewModel.carId.isNullOrEmpty()) return@observe
            mViewModel.refresh()
        }

        mInfoVB.ivUpDown.setOnClickListener {
            isShowRecycler = !isShowRecycler
            if (isShowRecycler) {
                showInfoRecycler()
                mInfoVB.recyclerCarInfo.visibility = View.VISIBLE
            } else {
                mInfoVB.recyclerCarInfo.visibility = View.GONE
            }
        }

        mInfoVB.ivUp.setOnClickListener {
            isShowRecycler = !isShowRecycler
            mInfoVB.ivUp.isSelected = isShowRecycler
            if (isShowRecycler) {
                showInfoRecycler()
                mInfoVB.recyclerCarInfo.visibility = View.VISIBLE
            } else {
                mInfoVB.recyclerCarInfo.visibility = View.GONE
            }
        }

        mInfoVB.ivCarSet.setOnClickListener {
            startActivityTo<InfoSetActivity>(requireContext())
        }

        mInfoVB.ivCarClose.setOnClickListener {
            isShowPopup = false
            mTrafficVB.tvCarCarShow.setText(R.string.desc_com_display)
            mInfoVB.llCarInfo.visibility = View.GONE
        }

        mInfoVB.ivCarRefresh.setOnClickListener {
            if (isFastClick()) return@setOnClickListener
            mViewModel.refresh2()
        }

        mInfoVB.tvCarHistory.setOnClickListener {
            startActivity(HistoryLineActivity::class.java, mViewModel.locaEntity)
        }

        mInfoVB.tvCarPhoto.setOnClickListener {
            startActivity(PhotosActivity::class.java, mViewModel.locaEntity)
        }

        mInfoVB.tvCarSingle.setOnClickListener {
            startActivity(SingleMonitorActivity::class.java, mViewModel.locaEntity)
        }

        mInfoVB.tvCarInfo.setOnClickListener {
            mViewModel.stopTime()
            mViewModel.isHidden = true
            launcher.launchAct<CarInfoActivity>(requireContext()) {
                putExtra(Keys.INTENT_CAR_ID, mViewModel.carId)
            }
        }

        mInfoVB.tvCarNavi.setOnClickListener {
            isLocation = false
            mNaviPopup.showAtLocation(requireActivity().window.decorView, mViewModel.locaEntity)
        }

        mInfoVB.tvCarCall.setOnClickListener {
            if (mViewModel.locaEntity?.drvPhone.isNullOrEmpty()) {
                R.string.desc_no_phone.toast(requireContext())
            } else {
                //跳转到拨号界面，同时传递电话号码
                val dialIntent =
                    Intent(
                        Intent.ACTION_DIAL,
                        Uri.parse("tel:${mViewModel.locaEntity?.drvPhone}")
                    )
                startActivity(dialIntent)
            }
        }
        //分享
        mInfoVB.ivCarShare.setOnClickListener {
//            WxShareUtil.instance.init(requireContext().applicationContext)
//            mViewModel.locaEntity?.let {
//                wxViewModel.shareLocation(it.carPlate, it.carId)
//            }

        }
    }

    private val mNaviPopup by lazy { ChooseNaviPopup(requireActivity()) }

    private fun startActivity(zClass: Class<*>, entity: GpsDetail?) {
        startActivity(
            Intent(requireContext(), zClass)
                .putExtra(Keys.INTENT_CAR_ID, entity?.carId)
                .putExtra(Keys.INTENT_PLATE, entity?.carPlate)
                .putExtra(Keys.INTENT_CAR_NAME, entity?.carName)
        )
    }

    private val launcher = registerResultOk { result ->
        mViewModel.isHidden = false
        mViewModel.carId?.let { mViewModel.startTime(it) }
    }


    /** 定位变化监听事件 */
    override fun onMyLocationChange(location: Location) {
        if (location.extras["errorCode"] != 0) {
            location.extras["errorInfo"]?.toastLong(requireContext())
            return
        }
        mLocationLatLng = LatLng(location.latitude, location.longitude)
        if (isLocation) mLocationLatLng?.run {
            isShowPopup = false
            mInfoVB.llCarInfo.visibility = View.GONE
            mTrafficVB.tvCarCarShow.setText(R.string.desc_com_display)
            if (mLatLng == null) {
                MapUtil.showMapLatLng(mMap!!, this)
            } else {
                MapUtil.showMapBounds(
                    mMap!!,
                    mViewModel.setBounds(mLatLng!!, this),
                    300
                )
            }
            mLocationMarker = MapUtil.addAndGetMarker(
                mMap!!, this, R.mipmap.ic_phone_location
            )
            return
        }
    }


}